from abc import ABCMeta, abstractmethod
from util.timeUtil import *
from util.searchPicUtil import *
from util.configUtil import *
import functools
import logging
import logging.config
from pynput.mouse import Controller as mController
from pynput.keyboard import Controller as kController
from pynput.keyboard import Key
from pynput import keyboard
from pynput.mouse import Button
from threadJob import *
import random
import gc
import os
from util.configUtil import *
from util.ocrBloodPercentage import *
import win32api

import numpy as np
from PIL import ImageGrab, Image
import cv2 as cv
import math
import datetime
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.triggers.interval import IntervalTrigger

logging.config.fileConfig("./util/logging.conf")
log = logging.getLogger("example")

"""
    父类描述：
        1、尽量各个职业都写到父类的共有层里面，实在有自己特殊在再写到自己的类里面
        2、如果子类有特定的定制，那么就在子类中对不同的部分进行定制，绝大部分还是用的父类中的代码
"""


class Player(metaclass=ABCMeta):
    # 通过构造函数传递过来大量的参数，通过key value值的方式来获取这些参数
    """
        构造函数：
            1、通过构造函数传递过来大量的参数，通过key value值的方式来获取这些参数
    """
    # 魔兽世界的NugComboBar，对应的捕捉高度和宽度
    NugComboBarDeltaX = 11
    NugComboBarDeltaY = 10

    # 魔兽世界底部按钮第一个激活与否，激活了会高亮
    Button1DeltaX = 18
    Button1DeltaY = 1
    ButtonWidth = 43

    WABloodBarY = getIniInt("./util", "xyBloodBar", "y1")
    WABloodBarWidth = getIniInt("./util", "xyBloodBar", "width")
    WABloodBarX = getIniInt("./util", "xyBloodBar", "x1")
    # 底部坦克的血条和自己血条之间y方向的位置差异
    WABlood1_Blood2_DeltaY = 26
    WABloodBarDeltaX = 3
    WABloodBarDeltaY = 3
    WABloodBarAvgColor = 185
    WA_SQUARE_ZFX_AvgColor = 230
    WA_SQUARE_ZFX = getIniInt("./util", "xyStatusSquare", "y1")
    WA_SQUARE_ZFX_X1 = getIniInt("./util", "xyStatusSquare", "x1")
    WA_SQUARE_ZFX_X2 = getIniInt("./util", "xyStatusSquare", "x1") + 1 * getIniInt("./util", "xyStatusSquare", "width")
    WA_SQUARE_ZFX_X3 = getIniInt("./util", "xyStatusSquare", "x1") + 2 * getIniInt("./util", "xyStatusSquare", "width")
    WA_SQUARE_ZFX_X4 = getIniInt("./util", "xyStatusSquare", "x1") + 3 * getIniInt("./util", "xyStatusSquare", "width")
    WA_SQUARE_ZFX_X5 = getIniInt("./util", "xyStatusSquare", "x1") + 4 * getIniInt("./util", "xyStatusSquare", "width")
    WA_SQUARE_ZFX_X6 = getIniInt("./util", "xyStatusSquare", "x1") + 5 * getIniInt("./util", "xyStatusSquare", "width")
    WA_SQUARE_ZFX_X7 = getIniInt("./util", "xyStatusSquare", "x1") + 6 * getIniInt("./util", "xyStatusSquare", "width")
    WA_SQUARE_ZFX_X8 = getIniInt("./util", "xyStatusSquare", "x1") + 7 * getIniInt("./util", "xyStatusSquare", "width")

    # 能量星星点数
    WA_STAR_Y = getIniInt("./util", "xyStar", "y1")
    WA_STAR_X1 = getIniInt("./util", "xyStar", "x1")
    WA_STAR_X2 = getIniInt("./util", "xyStar", "x1") + 1 * getIniInt("./util", "xyStar", "width")
    WA_STAR_X3 = getIniInt("./util", "xyStar", "x1") + 2 * getIniInt("./util", "xyStar", "width")
    WA_STAR_X4 = getIniInt("./util", "xyStar", "x1") + 3 * getIniInt("./util", "xyStar", "width")
    WA_STAR_X5 = getIniInt("./util", "xyStar", "x1") + 4 * getIniInt("./util", "xyStar", "width")
    WA_STAR_X6 = getIniInt("./util", "xyStar", "x1") + 5 * getIniInt("./util", "xyStar", "width")

    # za的武僧T的比较号的插件，判断酒池红了后需要吃就消醉拳，否则就危险的一个判断
    WA_WST_X = getIniInt("./util", "wst_za_red", "x")
    WA_WST_Y = getIniInt("./util", "wst_za_red", "y")
    WA_WST_W = getIniInt("./util", "wst_za_red", "w")
    WA_WST_H = getIniInt("./util", "wst_za_red", "h")
    WA_WST_AVG_COLOR = getIniInt("./util", "wst_za_red", "avgColor")

    # 蓝条

    # stopLoop = False

    stopShareLoop = False

    AOE = False

    # if else中的eelse键按的逻辑，有种是不触发的逻辑
    ELSEKEY_EMPTY = ''

    # 全局计数器
    countPlusPlus = 0

    schedulerInGame1 = BackgroundScheduler()
    schedulerInGame2 = BackgroundScheduler()
    schedulerInGame3 = BackgroundScheduler()
    schedulerInGame4 = BackgroundScheduler()
    schedulerInGame5 = BackgroundScheduler()
    schedulerInGame6 = BackgroundScheduler()
    schedulerInGame7 = BackgroundScheduler()
    schedulerInGame8 = BackgroundScheduler()
    schedulerInGame9 = BackgroundScheduler()
    schedulerInGame10 = BackgroundScheduler()

    def __init__(self, *args, **kwargs):
        # 构造函数
        # print("init %s" % self.__class__)
        # print("in player:self.frozenKeyPress1:" + str(args[0]))
        self.stillCanCreateNewThread = kwargs['stillCanCreateNewThread']
        self.frozenKeyPress = kwargs['frozenKeyPress']
        self.threadPoolKeyboard = kwargs['threadPoolKeyboard']
        self.threadPoolMouse = kwargs['threadPoolMouse']
        # self.race = kwargs['race']
        self.kb = kwargs['kb']
        self.ms = kwargs['ms']
        self.sem = kwargs['sem']
        self.gcDuringMousemoveObj = kwargs['gcDuringMousemoveObj']
        self.ui = kwargs['ui']
        return

    def setMainWindow(self, obj):
        self.MainWindow = obj

    def startScheduler1(self):
        self.schedulerInGame1.remove_all_jobs()
        self.schedulerInGame1.add_job(func=self.CallBackScheduler1, trigger='date',
                                      next_run_time=datetime.datetime.now(), id='yehaibo1')
        if self.schedulerInGame1.running != True:
            self.schedulerInGame1.start()
        return

    def startScheduler2(self):
        self.schedulerInGame2.remove_all_jobs()
        self.schedulerInGame2.add_job(func=self.CallBackScheduler2, trigger='date',
                                      next_run_time=datetime.datetime.now(), id='yehaibo2')
        if self.schedulerInGame2.running != True:
            self.schedulerInGame2.start()
        return

    def startScheduler3(self):
        self.schedulerInGame3.remove_all_jobs()
        self.schedulerInGame3.add_job(func=self.CallBackScheduler3, trigger='date',
                                      next_run_time=datetime.datetime.now(), id='yehaibo3')
        if self.schedulerInGame3.running != True:
            self.schedulerInGame3.start()
        return

    def startScheduler4(self):
        self.schedulerInGame4.remove_all_jobs()
        self.schedulerInGame4.add_job(func=self.CallBackScheduler4, trigger='date',
                                      next_run_time=datetime.datetime.now(), id='yehaibo4')
        if self.schedulerInGame4.running != True:
            self.schedulerInGame4.start()
        return

    def startScheduler5(self):
        self.schedulerInGame5.remove_all_jobs()
        self.schedulerInGame5.add_job(func=self.CallBackScheduler5, trigger='date',
                                      next_run_time=datetime.datetime.now(), id='yehaibo5')
        if self.schedulerInGame5.running != True:
            self.schedulerInGame5.start()
        return

    def startScheduler6(self):
        self.schedulerInGame6.remove_all_jobs()
        self.schedulerInGame6.add_job(func=self.CallBackScheduler6, trigger='date',
                                      next_run_time=datetime.datetime.now(), id='yehaibo6')
        if self.schedulerInGame6.running != True:
            self.schedulerInGame6.start()
        return

    def startScheduler7(self):
        self.schedulerInGame7.remove_all_jobs()
        self.schedulerInGame7.add_job(func=self.CallBackScheduler7, trigger='date',
                                      next_run_time=datetime.datetime.now(), id='yehaibo7')
        if self.schedulerInGame7.running != True:
            self.schedulerInGame7.start()
        return

    def startScheduler8(self):
        self.schedulerInGame8.remove_all_jobs()
        self.schedulerInGame8.add_job(func=self.CallBackScheduler8, trigger='date',
                                      next_run_time=datetime.datetime.now(), id='yehaibo8')
        if self.schedulerInGame8.running != True:
            self.schedulerInGame8.start()
        return

    def startScheduler9(self):
        self.schedulerInGame9.remove_all_jobs()
        self.schedulerInGame9.add_job(func=self.CallBackScheduler9, trigger='date',
                                      next_run_time=datetime.datetime.now(), id='yehaibo9')
        if self.schedulerInGame9.running != True:
            self.schedulerInGame9.start()
        return

    def startScheduler10(self):
        self.schedulerInGame10.remove_all_jobs()
        self.schedulerInGame10.add_job(func=self.CallBackScheduler10, trigger='date',
                                       next_run_time=datetime.datetime.now(), id='yehaibo10')
        if self.schedulerInGame10.running != True:
            self.schedulerInGame10.start()
        return

    # def stopScheduler1(self):
    #     self.schedulerInGame1.pause_job(job_id='yehaibo1')
    #     self.schedulerInGame2.pause_job(job_id='yehaibo2')
    #     self.schedulerInGame3.pause_job(job_id='yehaibo3')
    #     self.schedulerInGame4.pause_job(job_id='yehaibo4')
    #     self.schedulerInGame5.pause_job(job_id='yehaibo5')
    #     self.schedulerInGame6.pause_job(job_id='yehaibo6')
    #     self.schedulerInGame7.pause_job(job_id='yehaibo7')
    #     self.schedulerInGame8.pause_job(job_id='yehaibo8')
    #     self.schedulerInGame9.pause_job(job_id='yehaibo9')
    #     self.schedulerInGame10.pause_job(job_id='yehaibo10')

    def CallBackScheduler1(self):
        return

    def CallBackScheduler2(self):
        return

    def CallBackScheduler3(self):
        return

    def CallBackScheduler4(self):
        return

    def CallBackScheduler5(self):
        return

    def CallBackScheduler6(self):
        return

    def CallBackScheduler7(self):
        return

    def CallBackScheduler8(self):
        return

    def CallBackScheduler9(self):
        return

    def CallBackScheduler10(self):
        return

    '''
        祖先类中一个重要的对区域的平均像素的判断方法
        RGBMode:r;g;b;
        BigSmallmode:big,small   和区域缩成点后像素的平均值的比较
        triggerKey: 满足条件触发按的key
        loopNumber: 点击按键次数
    '''

    def pubAvgColorTiggerKeyBloodBarMode(self, x, y, w, h, avgNumber, RGBMode, BigSmallmode, triggerKey, sleepSecond,
                                         loopNumber, elseKey):
        # 平均像素，触发是否按键

        log.debug("ImageGrab图像抓取，像素识别前时分秒:" + str(datetime.datetime.now()))
        sleep(sleepSecond)  # 避免CPU占用太高
        ################################Button1##########################################
        imButton1 = ImageGrab.grab(
            bbox=(x, y, x + w, y + h))  # X1,Y1,X2,Y2
        imButton1_numpy = np.array(imButton1.getdata(), dtype='uint8').reshape(
            (imButton1.size[1], imButton1.size[0], 3))
        imButton1_pil = Image.fromarray(imButton1_numpy)
        rButton1, gButton1, bButton1 = imButton1_pil.split()  # 分离三通道
        avgButton1_color = 0
        if RGBMode == 'r':
            rButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
            avgButton1_color = rButton1.getpixel((0, 0))
        elif RGBMode == 'g':
            gButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
            avgButton1_color = gButton1.getpixel((0, 0))
        elif RGBMode == 'b':
            bButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
            avgButton1_color = bButton1.getpixel((0, 0))
        ################################End##########################################

        if BigSmallmode == 'big':
            if avgButton1_color > avgNumber:
                for i in range(1, loopNumber):
                    self.click(self.kb, triggerKey, 3)
                    sleep(0.2)
            else:
                if elseKey != '':
                    for i in range(1, 2):
                        self.click(self.kb, elseKey, 2)
                        sleep(0.1)
        elif BigSmallmode == 'small':
            if avgButton1_color < avgNumber:
                for i in range(1, loopNumber):
                    self.click(self.kb, triggerKey, 3)
                    sleep(0.2)
            else:
                if elseKey != '':
                    for i in range(1, 2):
                        self.click(self.kb, elseKey, 2)
                        sleep(0.1)
        return avgButton1_color

    def pubAvgColorTiggerKeyCDMode(self, x, y, w, h, avgNumber, RGBMode, BigSmallmode, triggerKey, sleepSecond,
                                   loopNumber, elseKey):
        # 平时按键一直按，某个区域内出现了，就停止按了，避免按键CPU，以及避免浪费技能(暴雨图腾模式)
        # elseKey：没有匹配上的时候，补基础按键

        log.debug("ImageGrab图像抓取，像素识别前时分秒:" + str(datetime.datetime.now()))
        sleep(sleepSecond)  # 避免CPU占用太高
        ################################Button1##########################################
        imButton1 = ImageGrab.grab(
            bbox=(x - w / 2, y - h / 2, x + w / 2, y + h / 2))  # X1,Y1,X2,Y2
        imButton1_numpy = np.array(imButton1.getdata(), dtype='uint8').reshape(
            (imButton1.size[1], imButton1.size[0], 3))
        imButton1_pil = Image.fromarray(imButton1_numpy)
        rButton1, gButton1, bButton1 = imButton1_pil.split()  # 分离三通道
        avgButton1_color = 0
        if RGBMode == 'r':
            rButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
            avgButton1_color = rButton1.getpixel((0, 0))
        elif RGBMode == 'g':
            gButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
            avgButton1_color = gButton1.getpixel((0, 0))
        elif RGBMode == 'b':
            bButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
            avgButton1_color = bButton1.getpixel((0, 0))
        ################################End##########################################

        if BigSmallmode == 'big':
            if avgButton1_color > avgNumber:
                print('xxxxxx11111')
                if elseKey != '':
                    for i in range(0, 1):
                        self.click(self.kb, elseKey, 2)
                        sleep(0.1)
            else:
                print('xxxxxx222222')
                for i in range(0, loopNumber):
                    self.click(self.kb, triggerKey, 3)
                    sleep(0.2)
        elif BigSmallmode == 'small':
            if avgButton1_color < avgNumber:
                print('xxxxxxaaaaa')
                for i in range(0, loopNumber):
                    self.click(self.kb, triggerKey, 3)
                    sleep(0.2)
            else:
                print('xxxxxxbbbbb')
                if elseKey != '':
                    for i in range(0, 1):
                        self.click(self.kb, elseKey, 2)
                        sleep(0.1)
        return avgButton1_color

    def pubAvgColorTiggerKeyBuffMode(self, x, y, w, h, avgNumber, RGBMode, BigSmallmode, triggerKey, sleepSecond,
                                     loopNumber, elseKey):
        # 某个区域内出现了，加强buffer开始，就按按到buffer瞬间消失

        log.debug("ImageGrab图像抓取，像素识别前时分秒:" + str(datetime.datetime.now()))
        sleep(sleepSecond)  # 避免CPU占用太高
        ################################Button1##########################################
        imButton1 = ImageGrab.grab(
            bbox=(x - w / 2, y - h / 2, x + w / 2, y + h / 2))  # X1,Y1,X2,Y2
        imButton1_numpy = np.array(imButton1.getdata(), dtype='uint8').reshape(
            (imButton1.size[1], imButton1.size[0], 3))
        imButton1_pil = Image.fromarray(imButton1_numpy)
        rButton1, gButton1, bButton1 = imButton1_pil.split()  # 分离三通道
        avgButton1_color = 0
        if RGBMode == 'r':
            rButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
            avgButton1_color = rButton1.getpixel((0, 0))
        elif RGBMode == 'g':
            gButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
            avgButton1_color = gButton1.getpixel((0, 0))
        elif RGBMode == 'b':
            bButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
            avgButton1_color = bButton1.getpixel((0, 0))
        ################################End##########################################

        if BigSmallmode == 'big':
            if avgButton1_color > avgNumber:
                for i in range(0, loopNumber):
                    self.click(self.kb, triggerKey, 3)
                    sleep(0.2)
            else:
                print('xxxxxx222222')
                if elseKey != '':
                    for i in range(0, 1):
                        self.click(self.kb, elseKey, 2)
                        sleep(0.1)
        elif BigSmallmode == 'small':
            if avgButton1_color < avgNumber:
                print('xxxxxxaaaaa')
                for i in range(0, loopNumber):
                    self.click(self.kb, triggerKey, 3)
                    sleep(0.2)
            else:
                print('xxxxxxbbbbb')
                if elseKey != '':
                    for i in range(0, 1):
                        self.click(self.kb, elseKey, 2)
                        sleep(0.1)
        return avgButton1_color

    def pubAvgColorTiggerKeyAndStopClickTwice(self, x, y, w, h, avgNumber, RGBMode, BigSmallmode, triggerKey,
                                              sleepSecond, loopNumber, stopx, stopy, stopwidth, stopheight, stopColor,
                                              stopSecond, stopModel, elseKey):
        # 第一轮坐标是血条，第二轮坐标是狂暴回血是否出来的坐标判断，防止多按一次，浪费技能

        log.debug("ImageGrab图像抓取，像素识别前时分秒:" + str(datetime.datetime.now()))

        ################################Button1##########################################
        imButton1 = ImageGrab.grab(
            bbox=(x, y, x + w, y + h))  # X1,Y1,X2,Y2
        imButton1_numpy = np.array(imButton1.getdata(), dtype='uint8').reshape(
            (imButton1.size[1], imButton1.size[0], 3))
        imButton1_pil = Image.fromarray(imButton1_numpy)
        rButton1, gButton1, bButton1 = imButton1_pil.split()  # 分离三通道
        avgButton1_color = 0
        if RGBMode == 'r':
            rButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
            avgButton1_color = rButton1.getpixel((0, 0))
        elif RGBMode == 'g':
            gButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
            avgButton1_color = gButton1.getpixel((0, 0))
        elif RGBMode == 'b':
            bButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
            avgButton1_color = bButton1.getpixel((0, 0))
        ################################End##########################################

        if BigSmallmode == 'big':
            if avgButton1_color > avgNumber:
                # 点击前判断是否已经释放了狂暴回复，避免连续点第二次浪费(wa弄出来的一个正方形颜色块)
                avgDruidBlood = self.pubAvgColorNoTrigger(stopx, stopy, stopwidth, stopheight, stopColor, stopSecond)
                if stopModel == 'small':
                    if avgDruidBlood < 230:
                        for i in range(1, loopNumber):
                            self.click(self.kb, triggerKey, 3)
                            sleep(0.2)
                    else:
                        if elseKey != '':
                            for i in range(0, 1):
                                self.click(self.kb, elseKey, 2)
                                sleep(0.1)
                else:
                    if elseKey != '':
                        for i in range(0, 1):
                            self.click(self.kb, elseKey, 2)
                            sleep(0.1)
            else:
                if elseKey != '':
                    for i in range(0, 1):
                        self.click(self.kb, elseKey, 2)
                        sleep(0.1)
        elif BigSmallmode == 'small':
            if avgButton1_color < avgNumber:
                # 点击前判断是否已经释放了狂暴回复，避免连续点第二次浪费(wa弄出来的一个正方形颜色块)
                print('wanyanwanyan')
                avgDruidBlood = self.pubAvgColorNoTrigger(stopx, stopy, stopwidth, stopheight, stopColor, stopSecond)
                if stopModel == 'small':
                    if avgDruidBlood < 230:
                        print('kaikaikaikai')
                        for i in range(1, loopNumber):
                            self.click(self.kb, triggerKey, 3)
                            sleep(0.2)
                            print('yehaiboyehaibo')
                    else:
                        if elseKey != '':
                            for i in range(0, 1):
                                self.click(self.kb, elseKey, 2)
                                sleep(0.1)
                else:
                    if elseKey != '':
                        for i in range(0, 1):
                            self.click(self.kb, elseKey, 2)
                            sleep(0.1)
            else:
                print('zuozuozuo')
                if elseKey != '':
                    for i in range(0, 1):
                        self.click(self.kb, elseKey, 2)
                        sleep(0.1)
        sleep(sleepSecond)  # 避免CPU占用太高
        return avgButton1_color

    def pubAvgColorNoTrigger(self, x, y, w, h, RGBMode, sleepSecond):
        # 仅仅获取颜色，没有任何动作
        log.debug("ImageGrab图像抓取，像素识别前时分秒:" + str(datetime.datetime.now()))
        sleep(sleepSecond)  # 避免CPU占用太高
        ################################Button1##########################################
        imButton1 = ImageGrab.grab(
            bbox=(x, y, x + w, y + h))  # X1,Y1,X2,Y2
        imButton1_numpy = np.array(imButton1.getdata(), dtype='uint8').reshape(
            (imButton1.size[1], imButton1.size[0], 3))
        imButton1_pil = Image.fromarray(imButton1_numpy)
        rButton1, gButton1, bButton1 = imButton1_pil.split()  # 分离三通道
        avgButton1_color = 0
        if RGBMode == 'r':
            rButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
            avgButton1_color = rButton1.getpixel((0, 0))
        elif RGBMode == 'g':
            gButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
            avgButton1_color = gButton1.getpixel((0, 0))
        elif RGBMode == 'b':
            bButton1.thumbnail((1, 1))  # 图片缩放为一个像素点
            avgButton1_color = bButton1.getpixel((0, 0))
        return avgButton1_color

    def removeFinishedTrhead(self, threadPool):
        log.debug("removeFinishedTrhead:为了避免关闭无效的线程而导致异常，源数组长度:" + str(len(threadPool)))
        threadPoolNewAvaliable = []
        for obj in threadPool:
            if obj.isAlive() == True:
                threadPoolNewAvaliable.append(obj)

        threadPool.clear()
        for obj in threadPoolNewAvaliable:
            threadPool.append(obj)
        log.debug("removeFinishedTrhead:为了避免关闭无效的线程而导致异常，之后数组长度:" + str(len(threadPool)))
        return

    def interruptAllByForce(self):
        # 强制打断、终止一切键盘鼠标操作77
        # 这里的顺序非常重要，会直接导致是否能打断，比如 h 上马是否可以上马
        if len(self.threadPoolMouse) > 0:
            self.removeFinishedTrhead(self.threadPoolMouse)
            for obj in self.threadPoolMouse:
                obj.terminate()
            self.threadPoolMouse.clear()

        if len(self.threadPoolKeyboard) > 0:
            for obj in self.threadPoolKeyboard:
                obj.terminate()
            self.removeFinishedTrhead(self.threadPoolKeyboard)
            self.threadPoolKeyboard.clear()
        #  stage2:
        # 终止掉别人| 所有的鼠标操作哦
        #  stage1:

        # stage3:

        self.sem.release()
        return

    def interruptAllByForceMouseUpDown(self):
        # 强制打断、终止一切键盘鼠标操作77
        # 这里的顺序非常重要，会直接导致是否能打断，比如 h 上马是否可以上马

        #  stage1:
        if len(self.threadPoolMouse) > 0:
            self.removeFinishedTrhead(self.threadPoolMouse)

        if len(self.threadPoolKeyboard) > 0:
            self.removeFinishedTrhead(self.threadPoolKeyboard)

        #  stage2:
        # 终止掉别人| 所有的鼠标操作哦
        if len(self.threadPoolKeyboard) > 0:
            for obj in self.threadPoolKeyboard:
                obj.terminate()
        if len(self.threadPoolMouse) > 0:
            for obj in self.threadPoolMouse:
                obj.terminate()

        # stage3:
        if len(self.threadPoolKeyboard) > 0:
            self.threadPoolKeyboard.clear()

        if len(self.threadPoolMouse) > 0:
            self.threadPoolMouse.clear()

        self.sem.release()
        return

    # 终止线程
    def _async_raise(self, tid, exctype):
        """raises the exception, perforself.ms cleanup if needed"""
        tid = ctypes.c_long(tid)
        if not inspect.isclass(exctype):
            exctype = type(exctype)
        res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
        if res == 0:
            raise ValueError("invalid thread id")
        elif res != 1:
            # """if it returns a number greater than one, you're in trouble,
            # and you should call it again with exc=NULL to revert the effect"""
            ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
            raise SystemError("PyThreadState_SetAsyncExc failed")
        return

    def stopThread(self, thread):
        self._async_raise(thread.ident, SystemExit)
        return

    def press(self, key):
        self.kb.press(key)
        self.kb.release(key)
        return

    def sleep(self, n):
        time.sleep(n)
        return

    def logAop(self, func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print('call %s():' % func.__name__)
            return func(*args, **kw)

        return wrapper

    # 修饰器参数的情况
    def loggerAop(self, pram):
        def logAop(func):
            @functools.wraps(func)
            def wrapper(*args, **kw):
                print('call %s(): and parsms is %s' % (func.__name__, pram))
                return func(*args, **kw)

            return wrapper

        return logAop

    # ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★下面是鼠标区域★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    # 监听鼠标
    def on_mouse_move_inThread(self, x, y):
        # 【鼠标移动】是非常有并发运行的需求的，因此不需要做不可并行的控制
        # with self.sem:
        strUuid = random.randint(1, 50000)
        log.debug('步骤 1:' + str(strUuid))
        # self.sem.release()
        # self.sem.acquire()
        # 动作代码
        position = format(self.ms.position)
        log.debug("-------------------->当前鼠标位置为:" + str(position) + "<--------------------")
        self.mouseMove(x, y)
        # self.sem.release()
        if self.gcDuringMousemoveObj == 'True':
            if int(datetime.datetime.now().strftime('%S')) % 20 == 0:
                log.debug("○○○○○释放了一次内存○○○○○")
                gc.collect()

        return

    # 监听鼠标
    def on_mouse_move_parent(self, x, y):
        try:
            # # 不放到线程做了，直接在这里触发
            # log.debug(str(i) + ':Pointer moved in inner to {0}'.format((x, y)))
            if self.ui.checkBox_XY_DISPLAY.isChecked() == True:
                self.MainWindow.setWindowTitle("XY:" + str(x) + "<----->" + str(y))
            if self.stillCanCreateNewThread:

                if int(datetime.datetime.now().strftime('%S')) % 4 == 0:
                    # # 鼠标消耗内存特别快，因此要控制线程的创建速度(delete)
                    # p = threadJob(target=self.on_mouse_move_inThread, args=(x, y))
                    # self.threadPoolMouse.append(p)
                    # p.start()
                    pass
                if int(datetime.datetime.now().strftime('%S')) % 4 == 0:
                    # removeFinishedTrhead(self.threadPoolKeyboard)
                    pass
                if int(datetime.datetime.now().strftime('%S')) % 6 == 0:
                    # 鼠标池中特别多，因此最好不好在这里频繁释放，否则直接影响游戏体验
                    # removeFinishedTrhead(self.threadPoolMouse)
                    pass
            return True
        except Exception as ex:
            log.error('异常信息:' + str(ex))
        finally:
            return True

    def on_mouse_click_parent(self, x, y, button, pressed):
        try:
            log.debug(
                "on_mouse_click_parent--1   是否还可以在内存中创建self.stillCanCreateNewThread:" + str(
                    self.stillCanCreateNewThread) + ", 左右键:" + str(
                    button) + ", pressed:" + str(pressed))
            if pressed == True:
                # 鼠标点击下去了
                if self.stillCanCreateNewThread:
                    log.debug('{0} at {1}'.format(
                        'Pressed' if pressed else 'Released',
                        (x, y)))
                    # Button.left
                    log.debug("on_mouse_click_parent button:" + str(button))
                    log.debug("on_mouse_click_parent--2--[比较重要的三个主要终止别人的处理顺序，不能错了]")
                    # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                    # self.interruptAllByForce()
                    # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
                    # 通过多肽调用这个函数，这个函数很有可能会被子类中重写了(不走线程)
                    self.on_mouse_click_son_before_thread(x, y, button, pressed)
                    if button == Button.left:
                        log.debug("on_mouse_click_inThread:点击了鼠标左边")
                        self.mouseLeftClickNoThread(x, y, pressed)
                    elif button == Button.right:
                        log.debug("on_mouse_click_inThread:点击了鼠标右边")
                        self.mouseRightClickNoThread(x, y, pressed)

                    # 上面是非线程的处理方式
                    # 下面是线程的处理方式
                    p1 = threadJob(target=self.on_mouse_click_inThread, args=(x, y, button, pressed))
                    self.threadPoolMouse.append(p1)
                    log.debug("on_mouse_click_parent--9:鼠标点击所新创建的线程，已经被创建。")
                    p1.start()

                return True
            else:
                # 鼠标释放开
                return True
        except Exception as ex:
            log.error('异常信息:' + str(ex))
        finally:
            return True

    # 沒有綫程方式的調用
    def on_mouse_click_son_before_thread(self, x, y, button, pressed):
        # 在鼠标点击，终止和打断其他动作（有些职业需要，有些不需要）??????????
        self.interruptAllByForce()
        return

    # 沒有綫程
    def mouseLeftClickNoThread(self, x, y, pressed):
        pass
        return

    # 沒有綫程
    def mouseRightClickNoThread(self, x, y, pressed):
        pass
        return

    def on_mouse_scroll_parent(self, x, y, dx, dy):
        try:
            if self.stillCanCreateNewThread:
                log.debug("on_mouse_scroll_parent:1")
                log.debug('on_mouse_scroll_parent {0} at {1}'.format(
                    'down' if dy < 0 else 'up',
                    (x, y)))
                # 通过多肽调用这个函数，这个函数很有可能会被子类中重写了
                self.on_mouse_scroll_son_before_thread(dx, dy)
                log.debug("on_mouse_scroll_parent:2")
                self.removeFinishedTrhead(self.threadPoolKeyboard)
                p = threadJob(target=self.on_mouse_scroll_inThread, args=(x, y, dx, dy))
                self.threadPoolMouse.append(p)
                log.debug("on_mouse_scroll_parent:3:创建线程成功!")
                p.start()
            return True
        except Exception as ex:
            log.error('异常信息:' + str(ex))
        finally:
            return True

    def on_mouse_scroll_son_before_thread(self, dx, dy):
        if dy < 0:
            # 滚轮向下
            pass
        elif dy > 0:
            # 滚轮向上
            pass
        return

    def on_mouse_scroll_inThread(self, x, y, dx, dy):

        with self.sem:
            self.sem.release()
            self.sem.acquire()
            # self.frozenMouseScroll = True
            if dy < 0:
                self.mouseDown(x, y)
            elif dy > 0:
                self.mouseUp(x, y)
            # 动作代码
            self.sem.release()
            # self.frozenMouseScroll = False
        return

    def on_mouse_click_inThread(self, x, y, button, pressed):
        # 【鼠标移动】是非常需要严格控制并发需求
        self.sem.release()
        self.sem.acquire()
        # 动作代码
        if button == Button.left:
            log.debug("on_mouse_click_inThread:点击了鼠标左边")
            self.mouseLeftClick(x, y)
        elif button == Button.right:
            log.debug("on_mouse_click_inThread:点击了鼠标右边")
            self.mouseRightClick(x, y)
        self.sem.release()
        return

    # ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★下面是键盘区域★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    # 键盘监听(顶层)
    def on_keyboard_press_parent(self, key):
        try:
            if key.char == 'z':
                self.ui.stopLoop = True
            else:
                # self.ui.stopLoop = False
                pass
        except Exception as ex:
            # self.ui.stopLoop = False
            pass

        try:
            if key.char == Key.cmd:
                self.ui.stopLoop = True
            else:
                # self.ui.stopLoop = False
                pass
        except Exception as ex:
            # self.ui.stopLoop = False
            pass

        log.debug("on_keyboard_press_parent:类里面了a1")
        try:
            # 这些拦截的是房子重复按，重复触发事件，进入一个死循环。这些按键上会承载一个图标。【press】和【release】都有的。
            # 阻止for循环，这些都是手不会直接按到的按键
            if key in (
                    Key.f1, Key.f2, Key.f3, Key.f4, Key.f5, Key.f6, Key.f7, Key.f8, Key.f9, Key.f10, Key.f11, Key.f12):
                return True
            if key not in (
                    Key.caps_lock, Key.shift, Key.shift_l, Key.shift_r, Key.ctrl_l, Key.ctrl_r, Key.alt_l, Key.alt_r,
                    Key.alt, Key.space, Key.cmd):
                # caps_lock, shift等这些，是允许过去的，是触发并发按键逻辑的。
                # 下面是预留按键，不运行从键盘进行出发，只能从代码进行触发
                if key.char in ('1', '2', '3', '4', '5', '6', '7', '8', '9', '0'):
                    return True
                if key.char in ('y', 'u', 'i', 'o', 'p', 'j', 'k', 'l', 'n', 'm'):
                    return True
                if key.char in ('=', '-', '\\', ']', '[', '\'', ';', '/', '.', ','):
                    return True
                # 避免重复键盘按键导致的重复多线程的生成
                if key.char in self.ui.RUNNING_KEY_POOL:
                    # 如果已经有运行的键位了，在这里就直接return，直接终止
                    return True
                else:
                    # 没有就添加到界面唯一的数组中，标记这个键位置已经运行了，个别按键不是大量的动作，又要求可以允许重复按的
                    if key.char not in ('v', 'r', 'q', 'w', 'x', 'c', 'h'):
                        self.ui.RUNNING_KEY_POOL.append(key.char)
                    else:
                        if 'a' in self.ui.RUNNING_KEY_POOL:
                            self.ui.RUNNING_KEY_POOL.remove('a')
                        if 'A' in self.ui.RUNNING_KEY_POOL:
                            self.ui.RUNNING_KEY_POOL.remove('A')
                        if 'q' in self.ui.RUNNING_KEY_POOL:
                            self.ui.RUNNING_KEY_POOL.remove('q')
                        if 'Q' in self.ui.RUNNING_KEY_POOL:
                            self.ui.RUNNING_KEY_POOL.remove('Q')
                    #
                    if key.char in ('a', 'A', 'q', 'Q'):
                        self.ui.stopLoop = False
                    # z(终止键，立刻释放公共数组)
                    if key.char in ('z', 'Z'):
                        self.ui.stopLoop = True
                        self.ui.RUNNING_KEY_POOL.clear()
                    # 到这里的逻辑是手指头实际会物理点击的按键，就会周到这里的流程
                    log.debug("on_keyboard_press_parent:类里面了a2")
                    if self.stillCanCreateNewThread:
                        self.removeFinishedTrhead(self.threadPoolKeyboard)
                        log.debug("on_keyboard_press_parent:类里面了a3")
                        self.on_keyboard_press_son_before_thread(key)

                        log.debug("on_keyboard_press_parent:类里面了a4")
                        # removeFinishedTrhead(self.threadPoolKeyboard)
                        log.debug("on_keyboard_press_parent:类里面了a5")
                        # 上面的代码，决定了是否要终止别人的
                        p = threadJob(target=self.on_keyboard_press_inThread, args=(key,))
                        self.threadPoolKeyboard.append(p)
                        log.debug('线程池中增加一个数组元素, 当前键盘pool长度:' + str(len(self.threadPoolKeyboard)))
                        p.start()
                        log.debug('线程开始start')
                        log.debug("on_keyboard_press_parent:类里面了a6")
                    return True
            else:
                # 左atl，右atl等稍微特殊得键，这些键位，暂时不用ui.RUNNING_KEY_POOL来进行管理，因为他们的入口键位a已经被管理起来了
                # 到这里的逻辑是手指头实际会物理点击的按键，就会周到这里的流程
                log.debug("on_keyboard_press_parent:类里面了a2")
                if self.stillCanCreateNewThread:
                    self.removeFinishedTrhead(self.threadPoolKeyboard)
                    log.debug("on_keyboard_press_parent:类里面了a3")
                    self.on_keyboard_press_son_before_thread(key)

                    log.debug("on_keyboard_press_parent:类里面了a4")
                    # removeFinishedTrhead(self.threadPoolKeyboard)
                    log.debug("on_keyboard_press_parent:类里面了a5")
                    # 上面的代码，决定了是否要终止别人的
                    p = threadJob(target=self.on_keyboard_press_inThread, args=(key,))
                    self.threadPoolKeyboard.append(p)
                    log.debug('线程池中增加一个数组元素, 当前键盘pool长度:' + str(len(self.threadPoolKeyboard)))
                    p.start()
                    log.debug('线程开始start')
                    log.debug("on_keyboard_press_parent:类里面了a6")
                return True
        except Exception as ex:
            log.error('异常信息:special key {0} pressed'.format(
                key) + str(ex))
        finally:
            # 普通的，1，2，3，4，5，6，7，8，9，0，都会经过这里的，所以不能打日志。
            # log.debug("on_keyboard_press:函数   key.char:" + str(key.char) + ", self.stillCanCreateNewThread:" + str(
            #     self.stillCanCreateNewThread) + "__5")
            # 这个返回至关重要，避免许多异常情况
            return True

    def on_keyboard_press_son_before_thread(self, key):
        # 有些按键是直接终止别人的，继续自己的，有些不是这样的，因此要区别对待【排列组合，情况非常多】/【也要超级符合每个职业的操作习惯】
        if key in (
                Key.f1, Key.f2, Key.f3, Key.f4, Key.f5, Key.f6, Key.f7, Key.f8, Key.f9, Key.f10, Key.f11,
                Key.f12):
            pass
        elif key == Key.enter:
            pass
        elif key == Key.space:
            pass
        elif key not in (
                Key.caps_lock, Key.shift, Key.shift_l, Key.shift_r, Key.ctrl_l, Key.ctrl_r, Key.alt_l, Key.alt_r,
                Key.alt, Key.space):
            if key.char == 'a':
                # 不终止别人，后面让只允许一个线程执行的逻辑来顺序排
                # ★★★★★★|★★★★★★|★★★★★★|★★★★★★|★★★★★★|★★★★★★|★★★★★★|★★★★★★|★★★★★★|★★★★★★|
                pass
            elif key.char == 'z':
                self.ui.stopLoop = True
                pass
            elif key.char == 'q':
                log.debug("on_keyboard_press_son_before_thread:函数   key.char:" + str(
                    key.char) + ", self.stillCanCreateNewThread:" + str(
                    self.stillCanCreateNewThread) + "__1.b")
                pass
                log.debug("on_keyboard_press_son_before_thread:函数   key.char:" + str(
                    key.char) + ", self.stillCanCreateNewThread:" + str(
                    self.stillCanCreateNewThread) + "__1.c")
            elif key.char == 'w':
                # 终止掉别人
                self.interruptAllByForce()
            elif key.char == 'r':
                # 终止掉别人
                # interruptAllByForce()
                pass
            elif key.char == 'g':
                # 终止掉别人
                self.interruptAllByForce()
            elif key.char == 'x':
                # 终止掉别人
                self.interruptAllByForce()
            elif key.char == 'v':
                # 终止掉别人
                self.interruptAllByForce()
            elif key.char == 'h':
                # 终止掉别人
                # self.interruptAllByForce()
                pass
            elif key.char == 'c':
                # 终止掉别人
                self.interruptAllByForce()
            elif key.char == 'e':
                pass
            elif key.char == 's':
                pass
            elif key.char == 'd':
                pass
            elif key.char == 'f':
                pass
            elif key.char == 'b':
                pass
        return

    # 键盘监听(最顶层的键盘监听函数)
    def on_keyboard_release_parent(self, key):
        try:
            # 这些拦截的是房子重复按，重复触发事件，进入一个死循环。这些按键上会承载一个图标。【press】和【release】都有的。
            # 阻止for循环，这些都是手不会直接按到的按键
            if key in (
                    Key.f1, Key.f2, Key.f3, Key.f4, Key.f5, Key.f6, Key.f7, Key.f8, Key.f9, Key.f10, Key.f11, Key.f12):
                return True
            if key not in (
                    Key.caps_lock, Key.shift, Key.shift_l, Key.shift_r, Key.ctrl_l, Key.ctrl_r, Key.alt_l, Key.alt_r,
                    Key.alt, Key.space, Key.cmd):
                # caps_lock, shift等这些，是允许过去的，是触发并发按键逻辑的。
                if key.char in ('1', '2', '3', '4', '5', '6', '7', '8', '9', '0'):
                    return True
                if key.char in ('y', 'u', 'i', 'o', 'p', 'j', 'k', 'l', 'n', 'm'):
                    return True
                if key.char in ('=', '-', '\\', ']', '[', '\'', ';', '/', '.', ','):
                    return True
            try:
                log.debug("进入了:on_keyboard_release_parent:函数   key.char:" + str(key.char))
            except Exception as ex:
                pass
            if self.stillCanCreateNewThread == False:
                log.debug(
                    "目前的 on_keyboard_release_parent self.stillCanCreateNewThread == False，也就是暂时无法在内存中创建新的线程。（通常我们可以停下来打字聊天了。）")
            log.debug('{0} released'.format(
                key))
            if key == keyboard.Key.esc:
                # Stop listener
                return False
            elif key == Key.cmd:
                log.debug('对于评级战场，按下windows键盘，就重新启动一次程序')
                self.ui.stopLoop = True
                # self.removeFinishedTrhead(self.threadPoolKeyboard)
                # self.removeFinishedTrhead(self.threadPoolMouse)
                # for obj in self.threadPoolKeyboard:
                #     obj.terminate()
                #     log.debug('循环杀死键盘的python线程,finished!')
                # for obj in self.threadPoolMouse:
                #     obj.terminate()
                #     log.debug('循环杀死鼠标的python线程,finished')
                # self.threadPoolKeyboard.clear()
                # self.threadPoolMouse.clear()
                # self.sem.release()
                self.windowCmd()
                return False
            elif key.char == 'z':
                self.z()
                log.debug(
                    "进入了:zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz11")
                log.debug('进入z的终止处理过程')
                self.removeFinishedTrhead(self.threadPoolKeyboard)
                self.removeFinishedTrhead(self.threadPoolMouse)
                for obj in self.threadPoolKeyboard:
                    obj.terminate()
                    log.debug('循环杀死键盘的python线程,finished!')
                for obj in self.threadPoolMouse:
                    obj.terminate()
                    log.debug('循环杀死鼠标的python线程,finished')
                self.threadPoolKeyboard.clear()
                self.threadPoolMouse.clear()
                self.sem.release()
                # 按Z，还顺便释放一次内存
                gc.collect()
                log.debug('清理完成后的键盘线程池长度为:' + str(len(self.threadPoolKeyboard)))
                log.debug('清理完成后的鼠标线程池长度为:' + str(len(self.threadPoolMouse)))
                log.debug(
                    "进入了:zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz22")
                return True
            else:
                # 起码return一个true，否则按a键，都不会再监听了
                return True
        except Exception as ex:
            log.error('异常信息:1 {0} pressed'.format(
                key) + str(ex))
        finally:
            # 这个返回至关重要，避免许多异常情况
            return True

    def on_keyboard_press_inThread(self, key):
        log.debug("on_keyboard_press_inThread:1")
        # with self.sem:
        log.debug("on_keyboard_press_inThread:2")
        self.sem.release()
        log.debug("on_keyboard_press_inThread self.sem.release() after 2")
        self.sem.acquire()
        log.debug("on_keyboard_press_inThread self.sem.acquire() after 3")
        self.frozenKeyPress = True
        # self.ui.stopLoop = False
        # 动作代码
        if key == Key.enter:
            log.debug('on_keyboard_press_inThread 线程内部打印的enter键位')
        elif key == Key.space:
            self.space()
        elif key == Key.f1:
            pass
        elif key == Key.f2:
            pass
        elif key == Key.f3:
            pass
        elif key == Key.f4:
            pass
        elif key == Key.f5:
            pass
        elif key == Key.f6:
            pass
        elif key == Key.f7:
            pass
        elif key == Key.f8:
            pass
        elif key == Key.f9:
            pass
        elif key == Key.f10:
            pass
        elif key == Key.f11:
            pass
        elif key == Key.f12:
            pass
        elif key == Key.cmd:
            self.windowCmd()
        elif key == Key.alt_l:
            # 2  alt
            self.parallelAlt2()
        elif key == Key.caps_lock:
            # 3   caps_lock
            self.parallelCap3()
        elif key == Key.shift:
            # 4   shift
            self.parallelShift4()
        elif key == Key.ctrl_l:
            # 5   ctrl
            self.parallelCtrl5()
        elif key == Key.ctrl_r:
            # 5   ctrl
            self.parallelCtrl6()
        # ========================================上面是特殊键盘，下面是a，b，c的键，key和key.char会报异常的
        elif key.char == 'a':
            log.debug("on_keyboard_press_inThread 按下键盘【a】后，正式开始执行：on_keyboard_press_inThread:3")
            self.a()
        elif key.char == 'z':
            log.debug('线程:z-->终止')
            self.ui.stopLoop = True
            # player.z(clearListen)
            # pauseListen(False)
            # clearListen(True)
            # self.threadPoolMouse.clear()
            log.debug('成功清空self.threadPoolKeyboard')
        elif key.char == 'q':
            self.q()
        elif key.char == 'w':
            self.w()
        elif key.char == 'r':
            self.r()
        elif key.char == 'g':
            self.g()
        elif key.char == 'x':
            self.x()
        elif key.char == 'v':
            self.v()
        elif key.char == 'h':
            self.h()
        elif key.char == 'c':
            self.c()
        elif key.char == 'e':
            self.e()
        elif key.char == 's':
            self.s()
        elif key.char == 'd':
            self.d()
        elif key.char == 'f':
            self.f()
        elif key.char == 'b':
            self.b()
        # 对漏掉的字符的判断
        elif key.char == 'm':
            self.m()
        elif key.char == 'n':
            self.n()
        elif key.char == 't':
            self.t()
        elif key.char == 'y':
            self.y()
        elif key.char == 'u':
            self.u()
        elif key.char == 'i':
            self.i()
        elif key.char == 'o':
            self.o()
        elif key.char == 'p':
            self.p()
        elif key.char == 'j':
            self.j()
        elif key.char == 'k':
            self.k()
        elif key.char == 'l':
            self.l()
        # 对特殊字符的判断---------------这里是原始自定义映射关系的地方---->/1 .2 ,3 '4 ;5 \6 ]7 [8 =9 -0
        elif key.char == '/':
            self.special1()
        elif key.char == '.':
            self.special2()
        elif key.char == ',':
            self.special3()
        elif key.char == '\'':
            self.special4()
        elif key.char == ';':
            self.special5()
        elif key.char == '\\':
            self.special6()
        elif key.char == ']':
            self.special7()
        elif key.char == '[':
            self.special8()
        elif key.char == '=':
            self.special9()
        elif key.char == '-':
            self.special10()
        elif key == Key.f12:
            print(
                '***********************yehaibo kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk***********************')
        elif key == Key.f13:
            self.f13()
        # 最多5个并发技能的按键------------------parallel--------------------> parallel:`1   Alt2     cap3    shift4   ctrl5
        elif key.char == '`':
            # 1  `
            self.parallel1()

        self.sem.release()

        self.frozenKeyPress = False
        return

    def click(self, kb, ascii, times):
        log.debug("进入click:" + str(times))
        for i in range(0, int(times)):
            self.kb.press(ascii)
            sleep(0.016)
            self.kb.release(ascii)
            sleep(0.016)
            log.debug("****************单击click press:" + str(ascii) + " button(times):" + str(i) + "/" + str(
                times) + "****************")
        log.debug("离开click:" + str(times))
        return

    # @abstractmethod  # 调用@abstractmethod规定子类必须有pay方法
    def a(self):
        log.debug('★按下键盘a后，需要开始执行的内容★')
        # sleep(10)
        for i in range(1, 888888):
            self.click(self.kb, '1', 8)
            sleep(0.08)
            self.click(self.kb, '2', 8)
            sleep(0.08)
            self.click(self.kb, '3', 8)
            sleep(0.08)
            self.click(self.kb, '4', 8)
            sleep(0.08)
            self.click(self.kb, '5', 8)
            sleep(0.08)
        log.debug('★按下键盘a后，需要over执行的内容★')
        return

    def z(self):
        # ====================================================[开始]终止定时器的操作====================================================
        try:
            # 终止所有的定时器
            self.schedulerInGame1.pause_job(job_id='yehaibo1')
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            self.schedulerInGame2.pause_job(job_id='yehaibo2')
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            self.schedulerInGame3.pause_job(job_id='yehaibo3')
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            self.schedulerInGame4.pause_job(job_id='yehaibo4')
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            self.schedulerInGame5.pause_job(job_id='yehaibo5')
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            self.schedulerInGame6.pause_job(job_id='yehaibo6')
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            self.schedulerInGame7.pause_job(job_id='yehaibo7')
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            self.schedulerInGame8.pause_job(job_id='yehaibo8')
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            self.schedulerInGame9.pause_job(job_id='yehaibo9')
        except Exception as ex:
            pass
        try:
            # 终止所有的定时器
            self.schedulerInGame10.pause_job(job_id='yehaibo10')
        except Exception as ex:
            pass
        # ====================================================[结束]终止定时器的操作====================================================
        try:
            # 清空界面运行池
            self.ui.RUNNING_KEY_POOL.clear()
        except Exception as ex:
            pass
        finally:
            self.ui.stopLoop = True
            log.debug('全局开关:' + str(self.ui.stopLoop))
        # 直接终止一切鼠标，键盘动作。
        self.interruptAllByForce()
        return

    def q(self):
        log.debug('★按下键盘q后，需要开始执行的内容★')
        for i in range(1, 888888):
            self.click(self.kb, '[', 8)
            sleep(0.08)
            self.click(self.kb, ']', 8)
        log.debug('★按下键盘q后，需要over执行的内容★')
        return

    def w(self):
        log.debug('★按下键盘w后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘w后，需要over执行的内容★')
        return

    def r(self):
        log.debug('★按下键盘r后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘r后，需要over执行的内容★')
        return

    def g(self):
        log.debug('★按下键盘g后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘g后，需要over执行的内容★')
        return

    def x(self):
        log.debug('★按下键盘x后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘x后，需要over执行的内容★')
        return

    def v(self):
        log.debug('★按下键盘v后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘v后，需要over执行的内容★')
        return

    def h(self):
        log.debug('★按下键盘h后，需要开始执行的内容★')
        # 骑马
        self.click(self.kb, Key.delete, 1)
        log.debug('★按下键盘h后，需要over执行的内容★')
        return

    def c(self):
        log.debug('★按下键盘c后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘c后，需要over执行的内容★')
        return

    def e(self):
        log.debug('★按下键盘e后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘e后，需要over执行的内容★')
        return

    def s(self):
        log.debug('★按下键盘s后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘s后，需要over执行的内容★')
        return

    def d(self):
        log.debug('★按下键盘d后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘d后，需要over执行的内容★')
        return

    def f(self):
        log.debug('★按下键盘f后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘f后，需要over执行的内容★')
        return

    def b(self):
        log.debug('★按下键盘b后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘b后，需要over执行的内容★')
        return

    def m(self):
        sleep(10)
        return

    def n(self):
        sleep(10)
        return

    def t(self):
        sleep(10)
        return

    def y(self):
        sleep(10)
        return

    def u(self):
        sleep(10)
        return

    def i(self):
        sleep(10)
        return

    def o(self):
        sleep(10)
        return

    def p(self):
        sleep(10)
        return

    def j(self):
        sleep(10)
        return

    def k(self):
        sleep(10)
        return

    def l(self):
        sleep(10)
        return

    # 对特殊字符的函数定义 ：/1 .2 ,3 '4 ;5 \6 ]7 [8 =9 -10 `11
    def special1(self):
        # /
        sleep(2)
        return

    def special2(self):
        # .
        sleep(2)
        return

    def special3(self):
        # ,
        sleep(2)
        return

    def special4(self):
        # '
        sleep(2)
        return

    def special5(self):
        # ;
        sleep(2)
        return

    def special6(self):
        # \
        sleep(2)
        return

    def special7(self):
        # ]
        sleep(2)
        return

    def special8(self):
        # [
        sleep(2)
        return

    def special9(self):
        # =
        sleep(2)
        return

    def special10(self):
        # -
        sleep(2)
        return

    def f12(self):
        # f12
        sleep(2)
        return

    def f13(self):
        # f13
        sleep(2)
        return

    def parallel1(self):
        # `--1
        sleep(2)
        return

    def parallelAlt2(self):
        # alt--2
        sleep(2)
        return

    def parallelCap3(self):
        # Cap--3
        sleep(2)
        return

    def parallelShift4(self):
        # Shift--4
        sleep(2)
        return

    def parallelCtrl5(self):
        # Ctrl--5
        sleep(2)
        return

    def parallelCtrl6(self):
        # Ctrl--5
        sleep(2)
        return

    def windowCmd(self):
        # ★★★★★★★★★★★★★★★★★★★★★★特殊的windows键盘，这个用户评级战场的重启★★★★★★★★★★★★★★★★★★★★★★
        for i in range(1, 4):
            # 如果不执行这里，就会在黑色的框上点击鼠标，那么就直接停止执行批处理了，也就无法终止程序，也就没法重启了
            self.ExecutemouseMove(1650, 850)
            self.click(self.kb, 'z', 2)
            self.ExecutemouseMove(1650, 850)
            sleep(0.3)
            self.ExecutemouseMove(1650, 850)
        self.ExecutemouseMove(1650, 850)
        sleep(0.3)
        self.ExecutemouseMove(1650, 850)
        # 避免批处理弹出黑框
        win32api.ShellExecute(0, 'open', getIni("../util", "bat", "batFilePath"), '', '', 0)
        # os.system(getIni("../util", "bat", "batFilePath"))
        self.ExecutemouseMove(1650, 850)
        return

    def space(self):
        log.debug('★按下键盘space后，需要开始执行的内容★')
        sleep(10)
        log.debug('★按下键盘space后，需要over执行的内容★')
        return

    def mouseUp(self, x, y):
        log.debug('★鼠标向上滚，需要开始执行的内容★')
        sleep(10)
        log.debug('★鼠标向上滚，需要over执行的内容★')
        return

    def mouseDown(self, x, y):
        log.debug('★鼠标向下滚，需要开始执行的内容★')
        sleep(10)
        log.debug('★鼠标向下滚，需要over执行的内容★')
        return

    def mouseMove(self, x, y):
        log.debug('★鼠标mouself.semove，需要开始执行的内容★')
        log.debug('★鼠标mouself.semove，需要over执行的内容★')
        return

    def ExecutemouseMove(self, x, y):
        log.debug('★鼠标mouself.semove，需要开始执行的内容★')
        self.ms.position = (0, 0)
        self.ms.move(x, y)
        log.debug('★鼠标mouself.semove，需要over执行的内容★')
        return

    def mouseLeftClick(self, x, y):
        log.debug('★鼠标click-left，需要开始执行的内容★')
        log.debug('★鼠标click-left，需要over执行的内容★')
        return

    def ExecutemouseLeftClick(self):
        log.debug('★纯执行鼠标动作，为了配合自动排评级战场★')
        self.ms.press(Button.left)
        self.ms.release(Button.left)
        return

    def mouseRightClick(self, x, y):
        log.debug('★鼠标click-right，需要开始执行的内容★')
        log.debug('★鼠标click-right，需要over执行的内容★')
        return

    def ExecutemouseRightClick(self):
        log.debug('★纯执行鼠标动作，为了配合自动排评级战场★')
        self.ms.press(Button.right)
        self.ms.release(Button.right)
        return

    def startListen(self):
        # wrong here
        # startMouseListen()
        # self.kb.
        pass

    def pubAvgColorCDNumberDeductInBlock(self, blockx, blocky, width, height, color, waitSeconds, pressKey, bigsmall,
                                         avgColor):
        avgColor1 = self.pubAvgColorNoTrigger(blockx, blocky, width, height, color, waitSeconds)
        if bigsmall == 'b':
            while avgColor1 > avgColor:
                self.click(self.kb, pressKey, 8)
                sleep(0.01)
                avgColor1 = self.pubAvgColorNoTrigger(blockx, blocky, width, height, color, waitSeconds)
        if bigsmall == 's':
            while avgColor1 < avgColor:
                self.click(self.kb, pressKey, 8)
                sleep(0.01)
                avgColor1 = self.pubAvgColorNoTrigger(blockx, blocky, width, height, color, waitSeconds)
        return

    def TimeSecondModZero(self, modNumber):
        now_time = datetime.datetime.now()
        # time1_str = now_time.strftime('%Y-%m-%d %H:%M:%S %f')
        SecondStr = now_time.strftime('%S')
        SecondInt = int(SecondStr)
        if SecondInt % modNumber == 0:
            return True
        else:
            return False

    def schedulerAction(self):
        pass
        return


if __name__ == '__main__':
    playerDebug = Player()
    # 调试主题函数
    print(playerDebug.TimeSecondModZero(2))
